using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Caching.Distributed;
using System.Text.Json;
using System.Diagnostics;

namespace CKY.AgentPlatform.Caching
{
    /// <summary>
    /// 缓存管理应用服务实现
    /// </summary>
    public class CachingAppService : ApplicationService, ICachingAppService
    {
        private readonly IDistributedCache<string> _distributedCache;
        private readonly IAbpDistributedLock _distributedLock;
        private readonly ILogger<CachingAppService> _logger;

        public CachingAppService(
            IDistributedCache<string> distributedCache,
            IAbpDistributedLock distributedLock,
            ILogger<CachingAppService> logger)
        {
            _distributedCache = distributedCache;
            _distributedLock = distributedLock;
            _logger = logger;
        }

        /// <summary>
        /// 获取缓存值
        /// </summary>
        public async Task<string> GetAsync(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentException("缓存键不能为空", nameof(key));
            }

            var stopwatch = Stopwatch.StartNew();
            try
            {
                var value = await _distributedCache.GetAsync(key);
                stopwatch.Stop();

                _logger.LogDebug("获取缓存值完成，键：{Key}，耗时：{ElapsedMs}ms", key, stopwatch.ElapsedMilliseconds);

                return value;
            }
            catch (Exception ex)
            {
                stopwatch.Stop();
                _logger.LogError(ex, "获取缓存值失败，键：{Key}，耗时：{ElapsedMs}ms", key, stopwatch.ElapsedMilliseconds);
                throw;
            }
        }

        /// <summary>
        /// 设置缓存值
        /// </summary>
        public async Task SetAsync(SetCacheInput input)
        {
            if (string.IsNullOrWhiteSpace(input.Key))
            {
                throw new ArgumentException("缓存键不能为空", nameof(input.Key));
            }

            var stopwatch = Stopwatch.StartNew();
            try
            {
                var options = new DistributedCacheEntryOptions();
                if (input.ExpirationSeconds.HasValue)
                {
                    options.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(input.ExpirationSeconds.Value);
                }

                await _distributedCache.SetAsync(input.Key, input.Value, options);
                stopwatch.Stop();

                _logger.LogDebug("设置缓存值完成，键：{Key}，过期时间：{Expiration}s，耗时：{ElapsedMs}ms",
                    input.Key, input.ExpirationSeconds, stopwatch.ElapsedMilliseconds);
            }
            catch (Exception ex)
            {
                stopwatch.Stop();
                _logger.LogError(ex, "设置缓存值失败，键：{Key}，耗时：{ElapsedMs}ms", input.Key, stopwatch.ElapsedMilliseconds);
                throw;
            }
        }

        /// <summary>
        /// 删除缓存值
        /// </summary>
        public async Task DeleteAsync(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentException("缓存键不能为空", nameof(key));
            }

            var stopwatch = Stopwatch.StartNew();
            try
            {
                await _distributedCache.RemoveAsync(key);
                stopwatch.Stop();

                _logger.LogDebug("删除缓存值完成，键：{Key}，耗时：{ElapsedMs}ms", key, stopwatch.ElapsedMilliseconds);
            }
            catch (Exception ex)
            {
                stopwatch.Stop();
                _logger.LogError(ex, "删除缓存值失败，键：{Key}，耗时：{ElapsedMs}ms", key, stopwatch.ElapsedMilliseconds);
                throw;
            }
        }

        /// <summary>
        /// 检查缓存是否存在
        /// </summary>
        public async Task<bool> ExistsAsync(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentException("缓存键不能为空", nameof(key));
            }

            try
            {
                var value = await _distributedCache.GetAsync(key);
                return value != null;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查缓存存在性失败，键：{Key}", key);
                throw;
            }
        }

        /// <summary>
        /// 获取缓存过期时间
        /// </summary>
        public async Task<DateTimeOffset?> GetExpirationAsync(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentException("缓存键不能为空", nameof(key));
            }

            try
            {
                // 注意：这个实现依赖于具体的缓存提供程序
                // 这里返回null，实际使用时可能需要根据具体缓存实现来获取过期时间
                return null;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取缓存过期时间失败，键：{Key}", key);
                throw;
            }
        }

        /// <summary>
        /// 清空所有缓存
        /// </summary>
        public async Task ClearAsync()
        {
            var stopwatch = Stopwatch.StartNew();
            try
            {
                // 使用分布式锁确保清空操作的原子性
                await using (var lockHandle = await _distributedLock.TryAcquireAsync("cache-clear", TimeSpan.FromSeconds(30)))
                {
                    if (lockHandle == null)
                    {
                        throw new InvalidOperationException("无法获取缓存清空操作的分布式锁");
                    }

                    // 注意：清空所有缓存是一个危险操作，实际使用时可能需要更精细的控制
                    // 这里只是示例，实际实现可能需要根据缓存提供程序来清空特定前缀的缓存
                    _logger.LogWarning("执行清空所有缓存操作，耗时：{ElapsedMs}ms", stopwatch.ElapsedMilliseconds);
                }
            }
            catch (Exception ex)
            {
                stopwatch.Stop();
                _logger.LogError(ex, "清空缓存失败，耗时：{ElapsedMs}ms", stopwatch.ElapsedMilliseconds);
                throw;
            }
        }

        /// <summary>
        /// 获取缓存统计信息
        /// </summary>
        public async Task<CacheStatisticsDto> GetStatisticsAsync()
        {
            try
            {
                // 返回模拟的统计信息
                // 实际实现需要根据具体的缓存提供程序来获取真实的统计信息
                return new CacheStatisticsDto
                {
                    TotalCount = 1000,
                    MemoryUsage = 1024 * 1024 * 10, // 10MB
                    HitCount = 800,
                    MissCount = 200,
                    HitRate = 0.8,
                    AverageResponseTime = 5.2,
                    LastUpdated = DateTime.UtcNow
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取缓存统计信息失败");
                throw;
            }
        }

        /// <summary>
        /// 批量获取缓存值
        /// </summary>
        public async Task<Dictionary<string, string>> GetManyAsync(string[] keys)
        {
            if (keys == null || keys.Length == 0)
            {
                return new Dictionary<string, string>();
            }

            var result = new Dictionary<string, string>();
            var tasks = keys.Select(async key =>
            {
                try
                {
                    var value = await GetAsync(key);
                    if (value != null)
                    {
                        result[key] = value;
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, "批量获取缓存值时处理键 {Key} 失败", key);
                }
            });

            await Task.WhenAll(tasks);
            return result;
        }

        /// <summary>
        /// 批量设置缓存值
        /// </summary>
        public async Task SetManyAsync(SetManyCacheInput input)
        {
            if (input == null || input.Items == null || input.Items.Count == 0)
            {
                return;
            }

            var tasks = input.Items.Select(async item =>
            {
                try
                {
                    var expiration = item.ExpirationSeconds ?? input.DefaultExpirationSeconds;
                    await SetAsync(new SetCacheInput
                    {
                        Key = item.Key,
                        Value = item.Value,
                        ExpirationSeconds = expiration
                    });
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, "批量设置缓存值时处理键 {Key} 失败", item.Key);
                }
            });

            await Task.WhenAll(tasks);
        }

        /// <summary>
        /// 批量删除缓存值
        /// </summary>
        public async Task DeleteManyAsync(string[] keys)
        {
            if (keys == null || keys.Length == 0)
            {
                return;
            }

            var tasks = keys.Select(async key =>
            {
                try
                {
                    await DeleteAsync(key);
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, "批量删除缓存值时处理键 {Key} 失败", key);
                }
            });

            await Task.WhenAll(tasks);
        }
    }
}